import os
import sys

import click
import uvicorn
from py_eureka_client import eureka_client
from re_common.baselibrary.utils.baseip import BaseIp
from tinydb import TinyDB

from app_main import app


def setEureka(server_port, app_name):
    server_host = str(BaseIp().GetLocalIPByPrefix("192.168"))
    server_port = server_port
    eureka_client.init(eureka_server="http://192.168.31.165:19000/eureka/",
                       app_name=app_name,
                       # 当前组件的主机名，可选参数，如果不填写会自动计算一个，如果服务和 eureka 服务器部署在同一台机器，请必须填写，否则会计算出 127.0.0.1
                       instance_host=server_host,
                       instance_port=server_port,
                       # 调用其他服务时的高可用策略，可选，默认为随机
                       ha_strategy=eureka_client.HA_STRATEGY_RANDOM)


@click.command()
@click.option('--port', default=8001, help='set port')
@click.option('--tags', default="main", help='set test')
@click.option('--app_name', default='fastapi-cjserver',
              type=click.Choice(['fastapi-cjserver', 'fastapi-cjserver-test']), help='set app_name')
def start(port, tags, app_name):
    """

    :param port: 传入端口号，默认为8001
    :param tags: main为调试正确的服务，test为调试服务
    :param app_name:
    :return:
    """
    try:
        pid = os.getpid()
        t_db = TinyDB(str(pid) + ".db")
        t_db.insert({str(pid) + "_port": port})
        t_db.insert({str(pid) + "_tags": tags})
        setEureka(port, app_name)
    except Exception as e:
        print(e)
    # ml = "uvicorn main:app --reload --host=0.0.0.0 --port={}".format(port)
    # os.system(ml)
    # loop = asyncio.ProactorEventLoop()
    # if sys.platform == 'win32':
    #     # asyncio 的事件循环有两种不同的实现：SelectorEventLoop和 ProactorEventLoop，它们的父类是AbstractEventLoop
    #     # SelectorEventLoop
    #
    #     selector = selectors.SelectSelector()
    #     loop = asyncio.SelectorEventLoop(selector)
    #     # 这个是asyncio默认使用的Event Loop实现，支持unix和windows平台
    #     # ProactorEventLoop
    #     # 这个是Windows平台专有的实现
    #     loop = asyncio.ProactorEventLoop()
    #     # asyncio.set_event_loop(loop)
    ip = str(BaseIp().GetLocalIPByPrefix("192.168"))
    if ip == "192.168.40.0" and port == 8001:
        print("使用 ProactorEventLoop")
        from asyncio import set_event_loop, ProactorEventLoop, get_event_loop, set_event_loop_policy, \
            WindowsProactorEventLoopPolicy
        from uvicorn import Config, Server
        # ProactorEventLoop 无法实现 reload 在uvicorn的历史版本中有过ProactorEventLoop，由于无法reload而放弃
        # set_event_loop(ProactorEventLoop())
        if sys.version_info.major >= 3 and sys.version_info.minor >= 7:
            set_event_loop_policy(WindowsProactorEventLoopPolicy())
        else:
            set_event_loop(ProactorEventLoop())
        server = Server(config=Config(app=app, host='0.0.0.0', port=port, reload=True))
        get_event_loop().run_until_complete(server.serve())
    else:
        # # # # 第一种运行方式
        # uvicorn.run(app='main:app', host='0.0.0.0', port=port, reload=True)
        uvicorn.workers.UvicornWorker
        pass
    # 第二种(放弃)
    # from asyncio import set_event_loop, ProactorEventLoop, get_event_loop
    # from uvicorn import Config, Server
    # # ProactorEventLoop 无法实现 reload 在uvicorn的历史版本中有过ProactorEventLoop，由于无法reload而放弃
    # set_event_loop(ProactorEventLoop())
    # server = Server(config=Config(app=app, host='0.0.0.0', port=port, reload=True))
    # get_event_loop().run_until_complete(server.serve())


if __name__ == '__main__':
    start()

# gunicorn main:app -b 0.0.0.0:8000 -w 4 -k uvicorn.workers.UvicornH11Worker --daemon
# 启动命令
# (端口号，默认不输入参数为8000) (tags,默认为main,测试需更改为test，正常使用为main)   (app_name，默认fastapi-cjserver)
# python main.py --port 8001 --tags main --app_name fastapi-cjserver
